package cn.net.autocode.platform.factory;

import cn.net.autocode.core.bean.ResultT;
import cn.net.autocode.platform.providers.container.DataSourceContainer;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

public class AutoCodeQueryFactory {

    public static ResultT queryDs(String dataSource,JSONObject data){
        Object object = queryDataSourceValue(dataSource,data);
        if (object instanceof JSONObject rs) {
            return ResultT.success(rs);
        } else if (object instanceof JSONArray rs) {
            return ResultT.success(rs);
        }else if(object instanceof List<?> rs){
            JSONArray jsonArray = new JSONArray(rs);
            return ResultT.success(jsonArray);
        }else if(object instanceof Map<?,?> rs){
            JSONObject jsonObject = new JSONObject(rs);
            return ResultT.success(jsonObject);
        }else if(object instanceof String
                || object instanceof Integer
                || object instanceof Long
                || object instanceof Double
                || object instanceof Float
                || object instanceof Byte
                || object instanceof Short
                || object instanceof Boolean){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("value", object);
            return ResultT.success(jsonObject);
        }else{
            throw new RuntimeException("数据源返回值类型只支持：JSONObject、JSONArray、List、Map及JAVA基本类型！");
        }
    }

    public static <T> T queryValue(String dataSource,Map<String,Object> param,Class<T> clazz) {
        JSONObject jsonObject = new JSONObject(param);
        return queryValue(dataSource,jsonObject,clazz);
    }

    @SuppressWarnings("unchecked")
    public static <T> T queryValue(String dataSource,JSONObject param,Class<T> clazz){
        Object value = queryDataSourceValue(dataSource,param);

        if (value == null) {
            if (clazz.equals(Integer.TYPE) || clazz.equals(Integer.class)) {
                value = 0;
            } else if (clazz.equals(Short.TYPE) || clazz.equals(Short.class)) {
                value = 0;
            } else if (clazz.equals(Long.TYPE) || clazz.equals(Long.class)) {
                value = 0L;
            } else if (clazz.equals(Float.TYPE) || clazz.equals(Float.class)) {
                value = 0.0f;
            } else if (clazz.equals(Double.TYPE) || clazz.equals(Double.class)) {
                value = 0.0;
            } else if (clazz.equals(Boolean.TYPE) || clazz.equals(Boolean.class)) {
                value = false;
            } else if (clazz.equals(Byte.TYPE) || clazz.equals(Byte.class)) {
                value = 0;
            }
        }
        if(value == null){
            return null;
        }else{
            return (T) value;
        }
    }

    public static Map<String,Object> queryMap(String dataSource,Map<String,Object> param){
        JSONObject paramJson = new JSONObject(param);
        return AutoCodeQueryFactory.queryMap(dataSource,paramJson);
    }

    public static Map<String,Object> queryMap(String dataSource,JSONObject param){
        Object object = AutoCodeQueryFactory.queryDataSourceValue(dataSource,param);
        if (object instanceof Map<?,?> value) {
            return (Map<String, Object>) value;
        }else{
            throw new RuntimeException(dataSource + "的返回值类型为"+object.getClass().getName());
        }
    }


    public static JSONArray queryJSONArray(String dataSource,Map<String,Object> param){
        JSONObject paramJson = new JSONObject(param);
        return AutoCodeQueryFactory.queryJSONArray(dataSource,paramJson);
    }

    public static JSONArray queryJSONArray(String dataSource,JSONObject param){
        Object object = AutoCodeQueryFactory.queryDataSourceValue(dataSource,param);
        if (object instanceof JSONArray value) {
            return value;
        }else{
            throw new RuntimeException(dataSource + "的返回值类型为"+object.getClass().getName());
        }
    }


    public static JSONObject queryJSON(String dataSource,Map<String,Object> param){
        JSONObject paramJson = new JSONObject(param);
        return AutoCodeQueryFactory.queryJSON(dataSource,paramJson);
    }

    public static JSONObject queryJSON(String dataSource,JSONObject param){
        Object object = AutoCodeQueryFactory.queryDataSourceValue(dataSource,param);
        if (object instanceof JSONObject value) {
            return value;
        }else{
            throw new RuntimeException(dataSource + "的返回值类型为"+object.getClass().getName());
        }
    }

    public static <T> List<T> queryListValue(String dataSource,Map<String,Object> param){
        JSONObject paramJson = new JSONObject(param);
        return AutoCodeQueryFactory.queryListValue(dataSource,paramJson);
    }

    public static <T> List<T> queryListValue(String dataSource,JSONObject param){
        Object object = AutoCodeQueryFactory.queryDataSourceValue(dataSource,param);
        if (object instanceof List<?> list) {
            return (List<T>) list;
        }else{
            throw new RuntimeException(dataSource + "的返回值类型为"+object.getClass().getName());
        }
    }



    private static Object queryDataSourceValue(String dataSource, JSONObject param){
        if (DataSourceContainer.methodMap.containsKey(dataSource)) {
            Method method = DataSourceContainer.methodMap.get(dataSource);
            Class<?>[] clazz = method.getParameterTypes();
            if (clazz.length != 1 || !clazz[0].isAssignableFrom(JSONObject.class)) {
                throw new RuntimeException(dataSource + "数据源定义有误！");
            }

            try {
                return method.invoke(DataSourceContainer.beanMap.get(dataSource), param);
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e.getCause());
            }
        } else {
            throw new RuntimeException(dataSource + "数据源没有定义！");
        }
    }
}
